home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hardcore Gamer Resource Kit
/
Hardcore Gamer Resource Kit - Disc 3.iso
/
screensavers
/
saver17.zip
/
VoodooLights
/
Sources
/
mat.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-07-12
|
10KB
|
390 lines
/*------------------------------------------------------/
/ /
/ Copyright 1997, SΘrgio Durte <smd@di.fct.unl.pt> /
/ /
/------------------------------------------------------*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include "defines.h"
#include "mat.h"
XYZ xyz_Zero = { 0.0, 0.0, 0.0 } ;
XYZW xyzw_Zero = { 0.0, 0.0, 0.0, 1.0 } ;
int mat_ipow( int b, int e )
{
int result = 1 ;
while( e-- ) result *= b ;
return result ;
}
void mat_scalev( Float s, XYZ *in, XYZ *out)
{
register Float f = s ;
out->x = in->x * f ;
out->y = in->y * f ;
out->z = in->z * f ;
}
Float mat_dotp( XYZ *a, XYZ *b)
{
return ((a->x) * (b->x) + (a->y) * (b->y) + (a->z) * (b->z)) ;
}
void mat_addv( XYZ *a, XYZ *b, XYZ *out )
{
out->x =a->x + b->x ;
out->y =a->y + b->y ;
out->z =a->z + b->z ;
}
void mat_subv( XYZ *a, XYZ *b, XYZ *out )
{
out->x =a->x - b->x ;
out->y =a->y - b->y ;
out->z =a->z - b->z ;
}
void mat_combv( Float t, XYZ *a, XYZ *b, XYZ *out )
{
out->x = t * a->x + b->x ;
out->y = t * a->y + b->y ;
out->z = t * a->z + b->z ;
}
Float mat_length( XYZ *a )
{
return (Float) sqrt ( sqr(a->x ) + sqr(a->y) + sqr(a->z) ) ;
}
Float mat_normalize( XYZ *a )
{
Float n, nn ;
nn = sqr(a->x) + sqr(a->y) + sqr(a->z) ;
if ( nn < ZERO ) return 0.0 ;
nn = (Float) sqrt(nn) ;
n = 1.0f / nn ;
a->x *= n ;
a->y *= n ;
a->z *= n ;
return nn ;
}
void mat_crossp( XYZ *a, XYZ *b, XYZ *out )
{
out->x = a->y * b->z - b->y * a->z ;
out->y = b->x * a->z - a->x * b->z ;
out->z = a->x * b->y - b->x * a->y ;
}
void mat_rotv( XYZ *e, XYZ *p, XYZ *o )
{
Float m = (Float)sqrt( sqr( p->y ) + sqr( p->z ) ) ;
Float im = 1.0f / m ;
o->x = m * e->x + p->x * e->z ;
o->y = ( -p->x * p->y * e->x + p->z * e->y ) * im + p->y * e->z ;
o->z = ( -p->x * p->z * e->x - p->y * e->y ) * im + p->z * e->z ;
}
void mat_randomDir( XYZ *d )
{
d->x = 1 - 2 * rnd() ;
d->y = 1 - 2 * rnd() ;
d->z = 1 - 2 * rnd() ;
mat_direction( d ) ;
}
void mat_printv( XYZ *a )
{
fprintf(stderr,">%12g\t%12g\t%12g\n",(double)a->x , (double)a->y , (double)a->z ) ;
}
void mat_printXYZW( XYZW *a )
{
Float x, y, z ;
x = (Float)(a->x / a->w) ;
y = (Float)(a->y / a->w) ;
z = (Float)(a->z / a->w) ;
fprintf(stderr,">%8g\t%8g\t%8g\t%8g\n",(double)a->x , (double)a->y , (double)a->z, (double)a->w) ;
fprintf(stderr,"3D ->[%8g\t%8g\t%8g]\n", (double)x, (double)y, (double)z ) ;
}
void mat_mult_m_XYZp( XYZ *v, Matrix a, XYZ *out )
{
out->x = v->x * a[0][0] + v->y * a[0][1] + v->z * a[0][2] + a[0][3] ;
out->y = v->x * a[1][0] + v->y * a[1][1] + v->z * a[1][2] + a[1][3] ;
out->z = v->x * a[2][0] + v->y * a[2][1] + v->z * a[2][2] + a[2][3] ;
}
void mat_mult_m_XYZWp( XYZ *v, Matrix a, XYZW *out )
{
out->x = v->x * a[0][0] + v->y * a[0][1] + v->z * a[0][2] + a[0][3] ;
out->y = v->x * a[1][0] + v->y * a[1][1] + v->z * a[1][2] + a[1][3] ;
out->z = v->x * a[2][0] + v->y * a[2][1] + v->z * a[2][2] + a[2][3] ;
out->w = v->x * a[3][0] + v->y * a[3][1] + v->z * a[3][2] + a[3][3] ;
}
void mat_mult_m_XYZv( XYZ *v, Matrix a, XYZ *out )
{
out->x = v->x * a[0][0] + v->y * a[0][1] + v->z * a[0][2] ;
out->y = v->x * a[1][0] + v->y * a[1][1] + v->z * a[1][2] ;
out->z = v->x * a[2][0] + v->y * a[2][1] + v->z * a[2][2] ;
}
void mat_multpm( XYZ *v, Matrix a, XYZW *out )
{
out->x = v->x * a[0][0] + v->y * a[0][1] + v->z * a[0][2] + a[0][3] ;
out->y = v->x * a[1][0] + v->y * a[1][1] + v->z * a[1][2] + a[1][3] ;
out->z = v->x * a[2][0] + v->y * a[2][1] + v->z * a[2][2] + a[2][3] ;
out->w = v->x * a[3][0] + v->y * a[3][1] + v->z * a[3][2] + a[3][3] ;
}
void mat_multvm(XYZ *v, Matrix a, XYZ *out )
{
out->x = v->x * a[0][0] + v->y * a[0][1] + v->z * a[0][2] ;
out->y = v->x * a[1][0] + v->y * a[1][1] + v->z * a[1][2] ;
out->z = v->x * a[2][0] + v->y * a[2][1] + v->z * a[2][2] ;
}
void mat_mult_tm_XYZv(XYZ *v, Matrix a, XYZ *out )
{
out->x = v->x * a[0][0] + v->y * a[1][0] + v->z * a[2][0] ;
out->y = v->x * a[0][1] + v->y * a[1][1] + v->z * a[2][1] ;
out->z = v->x * a[0][2] + v->y * a[1][2] + v->z * a[2][2] ;
}
void mat_mult_tm_XYZp(XYZ *v, Matrix a, XYZ *out )
{
out->x = v->x * a[0][0] + v->y * a[1][0] + v->z * a[2][0] ;
out->y = v->x * a[0][1] + v->y * a[1][1] + v->z * a[2][1] ;
out->z = v->x * a[0][2] + v->y * a[1][2] + v->z * a[2][2] ;
out->x -= a[0][0] * a[0][3] + a[1][0] * a[1][3] + a[2][0] * a[2][3] ;
out->y -= a[0][1] * a[0][3] + a[1][1] * a[1][3] + a[2][1] * a[2][3] ;
out->z -= a[0][2] * a[0][3] + a[1][2] * a[1][3] + a[2][2] * a[2][3] ;
}
void mat_multvtm(XYZ *v, Matrix a, XYZ *out )
{
out->x = v->x * a[0][0] + v->y * a[1][0] + v->z * a[2][0] ;
out->y = v->x * a[0][1] + v->y * a[1][1] + v->z * a[2][1] ;
out->z = v->x * a[0][2] + v->y * a[1][2] + v->z * a[2][2] ;
}
void mat_multpim(XYZ *v, Matrix a, XYZ *out )
{
out->x = v->x * a[0][0] + v->y * a[1][0] + v->z * a[2][0] ;
out->y = v->x * a[0][1] + v->y * a[1][1] + v->z * a[2][1] ;
out->z = v->x * a[0][2] + v->y * a[1][2] + v->z * a[2][2] ;
out->x -= a[0][0] * a[0][3] + a[1][0] * a[1][3] + a[2][0] * a[2][3] ;
out->y -= a[0][1] * a[0][3] + a[1][1] * a[1][3] + a[2][1] * a[2][3] ;
out->z -= a[0][2] * a[0][3] + a[1][2] * a[1][3] + a[2][2] * a[2][3] ;
}
void mat_summ( Matrix a, Matrix b, Matrix out )
{
register int k;
for(k=3 ; k>=0 ; k--)
{
out[0][k] = a[0][k] + b[0][k] ;
out[1][k] = a[1][k] + b[1][k] ;
out[2][k] = a[2][k] + b[2][k] ;
out[3][k] = a[3][k] + b[3][k] ;
}
}
void mat_subm( Matrix a, Matrix b, Matrix out)
{
register int k;
for(k=3 ; k>=0 ; k--)
{
out[0][k] = a[0][k] - b[0][k] ;
out[1][k] = a[1][k] - b[1][k] ;
out[2][k] = a[2][k] - b[2][k] ;
out[3][k] = a[3][k] - b[3][k] ;
}
}
void mat_multm(Matrix a, Matrix b, Matrix out )
{
register int i, j ;
for(i=3 ; i>=0 ; i--)
for(j=3 ; j>=0 ; j--)
out[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j] + a[i][3] * b[3][j] ;
}
void mat_idm( Matrix out )
{
register int i, j ;
for( i = 0 ; i < 4 ; i++ )
for( j = 0 ; j < 4 ; j++ ) out[i][j] = ( i == j ? 1.0f : 0.0f ) ;
}
void mat_transl( XYZ *v, Matrix out )
{
mat_idm( out ) ;
out[0][3] = v->x ;
out[1][3] = v->y ;
out[2][3] = v->z ;
}
void mat_scale( XYZ *v, Matrix out )
{
mat_idm( out );
out[0][0] = v->x ;
out[1][1] = v->y ;
out[2][2] = v->z ;
}
void mat_rotx(Float degrees, Matrix out )
{
Float c, s ;
c = (Float)cos( RAD( degrees ) ) ;
s = (Float)sin( RAD( degrees) ) ;
mat_idm( out ) ;
out[1][1] = c ;
out[2][2] = c ;
out[1][2] = -s ;
out[2][1] = s ;
}
void mat_roty(Float degrees, Matrix out )
{
Float c, s ;
c = (Float)cos( RAD( degrees ) ) ;
s = (Float)sin( RAD( degrees ) ) ;
mat_idm( out ) ;
out[0][0] = c ;
out[2][2] = c ;
out[0][2] = s ;
out[2][0] = -s ;
}
void mat_rotz(Float degrees, Matrix out )
{
Float c,s;
c = (Float)cos( RAD( degrees ) ) ;
s = (Float)sin( RAD( degrees ) ) ;
mat_idm( out ) ;
out[0][0] = c ;
out[1][1] = c ;
out[0][1] = -s ;
out[1][0] = s ;
}
void mat_shearx( Float sy, Float sz, Matrix out )
{
mat_idm( out ) ;
out[1][0] = sy ;
out[2][0] = sz ;
}
void mat_sheary( Float sx, Float sz, Matrix out )
{
mat_idm( out ) ;
out[0][1] = sx ;
out[2][1] = sz ;
}
void mat_shearz( Float sx, Float sy, Matrix out )
{
mat_idm( out ) ;
out[0][2] = sx ;
out[1][2] = sy ;
}
void mat_transpose( Matrix in, Matrix out )
{
int i, j ;
for( i = 0 ; i < 4 ; i++ )
for( j = 0 ; j < 4 ; j++ ) out[i][j] = in[j][i] ;
}
void mat_invm( Matrix m, Matrix out )
{
register int i, j ;
mat_idm( out ) ;
for ( i = 0 ; i < 3 ; i++ )
for ( j = 0 ; j < 3; j++ )
out[i][j] = m[j][i] ;
for ( i = 0 ; i < 3 ; i++ )
out[i][3] = -( m[0][i] * m[0][3] + m[1][i] * m[1][3] + m[2][i] * m[2][3] ) ;
}
void mat_printm( char *s, Matrix m )
{
int j ;
fprintf(stderr, "%s\n", s) ;
for( j = 0 ; j < 4 ; j++ )
fprintf(stderr, "%8.6g\t%8.6g\t%8.6g\t%8.6g\n", m[j][0], m[j][1], m[j][2], m[j][3] ) ;
}
#define mat_Accumulate if( temp >= 0.0 ) pos += temp ; else neg += temp
#define Precision_Limit 1e-15
Bool mat_ainvm( Matrix i , Matrix o )
{
double det_1 ;
double pos, neg, temp ;
pos = neg = 0.0 ;
temp = i[0][0] * i[1][1] * i[2][2] ;
mat_Accumulate ;
temp = i[0][1] * i[1][2] * i[2][0] ;
mat_Accumulate ;
temp = i[0][2] * i[1][0] * i[2][1] ;
mat_Accumulate ;
temp = -i[0][2] * i[1][1] * i[2][0] ;
mat_Accumulate ;
temp = -i[0][1] * i[1][0] * i[2][2] ;
mat_Accumulate ;
temp = -i[0][0] * i[1][2] * i[2][1] ;
mat_Accumulate ;
det_1 = pos + neg ;
if( det_1 == 0.0 || fabs( det_1 / ( pos - neg )) < Precision_Limit )
{
fprintf( stderr," Singular Matrix, cannot invert.\n");
return False ;
}
det_1 = 1.0 / det_1 ;
o[0][0] = (Float)( ( i[1][1] * i[2][2] - i[1][2] * i[2][1] ) * det_1 ) ;
o[1][0] = (Float)(-( i[1][0] * i[2][2] - i[1][2] * i[2][0] ) * det_1 ) ;
o[2][0] = (Float)( ( i[1][0] * i[2][1] - i[1][1] * i[2][0] ) * det_1 ) ;
o[3][0] = 0.0 ;
o[0][1] = (Float)(-( i[0][1] * i[2][2] - i[0][2] * i[2][1] ) * det_1 ) ;
o[1][1] = (Float)( ( i[0][0] * i[2][2] - i[0][2] * i[2][0] ) * det_1 ) ;
o[2][1] = (Float)(-( i[0][0] * i[2][1] - i[0][1] * i[2][0] ) * det_1 ) ;
o[3][1] = 0.0 ;
o[0][2] = (Float)( ( i[0][1] * i[1][2] - i[0][2] * i[1][1] ) * det_1 ) ;
o[1][2] = (Float)(-( i[0][0] * i[1][2] - i[0][2] * i[1][0] ) * det_1 ) ;
o[2][2] = (Float)( ( i[0][0] * i[1][1] - i[0][1] * i[1][0] ) * det_1 ) ;
o[3][2] = 0.0 ;
o[0][3] = (Float)(- ( i[0][3] * o[0][0] + i[1][3] * o[0][1] + i[2][3] * o[0][2] )) ;
o[1][3] = (Float)(- ( i[0][3] * o[1][0] + i[1][3] * o[1][1] + i[2][3] * o[1][2] )) ;
o[2][3] = (Float)(- ( i[0][3] * o[2][0] + i[1][3] * o[2][1] + i[2][3] * o[2][2] )) ;
o[3][3] = 1.0 ;
return True ;
}